package client;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

import uk.co.caprica.vlcj.player.MediaPlayer;
import uk.co.caprica.vlcj.player.MediaPlayerEventAdapter;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.DefaultFullScreenStrategy;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.FullScreenStrategy;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import uk.co.caprica.vlcj.runtime.windows.WindowsCanvas;

import com.sun.jna.Native;
import com.sun.jna.platform.WindowUtils;
import java.io.File;
import uk.co.caprica.vlcj.test.VlcjTest;

import java.applet.*;

public class TestPlayer extends Applet {

    // Ventana principal
    private JFrame mainFrame;
    private Canvas videoSurface;
    // Panel de control
    private JPanel controlsPanel;
    private MediaPlayerFactory mediaPlayerFactory;
    private EmbeddedMediaPlayer mediaPlayer;
    private Client dirhost;

    public static void main(String[] args) throws Exception {

        Native.setProtected(false);
        setLookAndFeel();

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                TestPlayer testPlayer = new TestPlayer();
            }
        });
    }
    
    public void init()  {
        try {
            Native.setProtected(false);
            setLookAndFeel();

            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    TestPlayer testPlayer = new TestPlayer();
                }
            });
        } catch (Exception ex) {
            Logger.getLogger(TestPlayer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static void setLookAndFeel() throws Exception {
        String lookAndFeelClassName = null;
        LookAndFeelInfo[] lookAndFeelInfos = UIManager.getInstalledLookAndFeels();
        for (LookAndFeelInfo lookAndFeel : lookAndFeelInfos) {
            if ("Nimbus".equals(lookAndFeel.getName())) {
                lookAndFeelClassName = lookAndFeel.getClassName();
            }
        }
        if (lookAndFeelClassName == null) {
            lookAndFeelClassName = UIManager.getSystemLookAndFeelClassName();
        }
        UIManager.setLookAndFeel(lookAndFeelClassName);
    }

    public TestPlayer() {
        if (RuntimeUtil.isWindows()) {
            // If running on Windows and you want the mouse/keyboard event hack...
            videoSurface = new WindowsCanvas();
        } else {
            videoSurface = new Canvas();
        }

        videoSurface.setBackground(Color.black);
        videoSurface.setSize(720, 240); // Only for initial layout

        // Since we're mixing lightweight Swing components and heavyweight AWT
        // components this is probably a good idea
        JPopupMenu.setDefaultLightWeightPopupEnabled(false);

        TestPlayerMouseListener mouseListener = new TestPlayerMouseListener();
        videoSurface.addMouseListener(mouseListener);
        videoSurface.addMouseMotionListener(mouseListener);
        videoSurface.addMouseWheelListener(mouseListener);
        videoSurface.addKeyListener(new TestPlayerKeyListener());

        List<String> vlcArgs = new ArrayList<String>();

        vlcArgs.add("--no-plugins-cache");
        vlcArgs.add("--no-video-title-show");
        vlcArgs.add("--no-snapshot-preview");
        vlcArgs.add("--quiet");
        vlcArgs.add("--quiet-synchro");


        mainFrame = new JFrame("Reproductor");
        // Accion al cerrar el cliente
        mainFrame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                dirhost.send_request("quit");
            }
        });
        FullScreenStrategy fullScreenStrategy = new DefaultFullScreenStrategy(mainFrame);

        mediaPlayerFactory = new MediaPlayerFactory(vlcArgs.toArray(new String[vlcArgs.size()]));

        mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer(fullScreenStrategy);
        mediaPlayer.setVideoSurface(mediaPlayerFactory.newVideoSurface(videoSurface));
        mediaPlayer.setPlaySubItems(true);

        mediaPlayer.setEnableKeyInputHandling(false);
        mediaPlayer.setEnableMouseInputHandling(false);

        // You can set a logo like this if you like...
        File logoFile = new File("build/classes/icons/vlcj-logo.png");
        if (logoFile.exists()) {
            mediaPlayer.setLogoFile(logoFile.getAbsolutePath());
            mediaPlayer.setLogoOpacity(0.0f);
            mediaPlayer.setLogoLocation(100, 100);
            mediaPlayer.enableLogo(true);
        }

        dirhost = new Client();
        controlsPanel = new PlayerControlsPanel(mediaPlayer, dirhost);

        mainFrame.setLayout(new BorderLayout());
        mainFrame.setBackground(Color.black);
        mainFrame.add(videoSurface, BorderLayout.CENTER);
        mainFrame.add(controlsPanel, BorderLayout.SOUTH);
        //mainFrame.setJMenuBar(buildMenuBar());
        mainFrame.pack();
        mainFrame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent evt) {

                if (videoSurface instanceof WindowsCanvas) {
                    ((WindowsCanvas) videoSurface).release();
                }

                if (mediaPlayer != null) {
                    mediaPlayer.release();
                    mediaPlayer = null;
                }

                if (mediaPlayerFactory != null) {
                    mediaPlayerFactory.release();
                    mediaPlayerFactory = null;
                }

                System.exit(0);
            }
        });

        // Global AWT key handler, you're better off using Swing's InputMap and
        // ActionMap with a JFrame - that would solve all sorts of focus issues too
        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {

            @Override
            public void eventDispatched(AWTEvent event) {
                if (event instanceof KeyEvent) {
                    KeyEvent keyEvent = (KeyEvent) event;
                    if (keyEvent.getID() == KeyEvent.KEY_PRESSED) {
                        if (keyEvent.getKeyCode() == KeyEvent.VK_F12) {
                            controlsPanel.setVisible(!controlsPanel.isVisible());
                            mainFrame.getJMenuBar().setVisible(!mainFrame.getJMenuBar().isVisible());
                            mainFrame.invalidate();
                            mainFrame.validate();
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_A) {
                            mediaPlayer.setAudioDelay(mediaPlayer.getAudioDelay() - 50000);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_S) {
                            mediaPlayer.setAudioDelay(mediaPlayer.getAudioDelay() + 50000);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_1) {
                            mediaPlayer.setTime(60000 * 1);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_2) {
                            mediaPlayer.setTime(60000 * 2);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_3) {
                            mediaPlayer.setTime(60000 * 3);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_4) {
                            mediaPlayer.setTime(60000 * 4);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_5) {
                            mediaPlayer.setTime(60000 * 5);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_6) {
                            mediaPlayer.setTime(60000 * 6);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_7) {
                            mediaPlayer.setTime(60000 * 7);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_8) {
                            mediaPlayer.setTime(60000 * 8);
                        } else if (keyEvent.getKeyCode() == KeyEvent.VK_9) {
                            mediaPlayer.setTime(60000 * 9);
                        }
                    }
                }
            }
        }, AWTEvent.KEY_EVENT_MASK);

        mainFrame.setVisible(true);

        mediaPlayer.addMediaPlayerEventListener(new TestPlayerMediaPlayerEventListener());

        // Won't work with OpenJDK or JDK1.7, requires a Sun/Oracle JVM (currently)
        boolean transparentWindowsSupport = true;
        try {
            Class.forName("com.sun.awt.AWTUtilities");
        } catch (Exception e) {
            transparentWindowsSupport = false;
        }

        if (transparentWindowsSupport) {
            final Window test = new Window(null, WindowUtils.getAlphaCompatibleGraphicsConfiguration()) {

                @Override
                public void paint(Graphics g) {
                    Graphics2D g2 = (Graphics2D) g;

                    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);

                    g.setColor(Color.white);
                    g.fillRoundRect(100, 150, 100, 100, 32, 32);

                    g.setFont(new Font("Sans", Font.BOLD, 32));
                    g.drawString("Heavyweight overlay test", 100, 300);
                }
            };

            test.setBackground(new Color(0, 0, 0, 0)); // This is what you do in JDK7
        }
    }

    private final class TestPlayerMediaPlayerEventListener extends MediaPlayerEventAdapter {

        @Override
        public void mediaChanged(MediaPlayer mediaPlayer) {
            System.out.println("mediaChanged");
        }

        @Override
        public void finished(MediaPlayer mediaPlayer) {
            System.out.println("finished");
        }

        @Override
        public void paused(MediaPlayer mediaPlayer) {
            System.out.println("pause");
        }

        @Override
        public void playing(MediaPlayer mediaPlayer) {
            System.out.println("playing");
        }

        @Override
        public void stopped(MediaPlayer mediaPlayer) {
            System.out.println("stopped");
        }

        @Override
        public void error(MediaPlayer mediaPlayer) {
        }
    }

    /**
     *
     */
    private final class TestPlayerMouseListener extends MouseAdapter {

        @Override
        public void mouseMoved(MouseEvent e) {
            //Logger.trace("mouseMoved(e={})", e);
        }

        @Override
        public void mousePressed(MouseEvent e) {
            //Logger.debug("mousePressed(e={})", e);
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            //Logger.debug("mouseReleased(e={})", e);
        }

        @Override
        public void mouseWheelMoved(MouseWheelEvent e) {
            //Logger.debug("mouseWheelMoved(e={})", e);
        }

        @Override
        public void mouseEntered(MouseEvent e) {
            //Logger.debug("mouseEntered(e={})", e);
        }

        @Override
        public void mouseExited(MouseEvent e) {
            //Logger.debug("mouseExited(e={})", e);
        }
    }

    /**
     *
     */
    private final class TestPlayerKeyListener extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
            //Logger.debug("keyPressed(e={})", e);
        }

        @Override
        public void keyReleased(KeyEvent e) {
            //Logger.debug("keyReleased(e={})", e);
        }

        @Override
        public void keyTyped(KeyEvent e) {
            //Logger.debug("keyTyped(e={})", e);
        }
    }
}
